package com.zapi.ai.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zapi.ai.model.ApiMetadata;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * API执行服务 - 动态执行API调用
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiExecutorService {
    
    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Value("${server.port:8080}")
    private int serverPort;
    
    @Value("${server.servlet.context-path:}")
    private String contextPath;
    
    /**
     * 执行API调用
     * 
     * @param api API元数据
     * @param parameters 参数Map
     * @param token JWT token（如果需要认证）
     * @return API执行结果
     */
    public ApiExecutionResult executeApi(ApiMetadata api, Map<String, Object> parameters, String token) {
        try {
            log.info("执行API: {} {}, 参数: {}", api.getMethod(), api.getPath(), parameters);
            
            String url = buildUrl(api, parameters);
            HttpMethod method = HttpMethod.valueOf(api.getMethod());
            HttpHeaders headers = buildHeaders(api, token);
            Object requestBody = buildRequestBody(api, parameters);
            
            HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                    url, method, entity, String.class);
            
            String responseBody = response.getBody();
            
            log.info("API响应: HTTP={}, Body={}", response.getStatusCodeValue(), responseBody);
            
            // 解析业务结果，判断是否真正成功
            boolean businessSuccess = checkBusinessSuccess(responseBody);
            
            if (businessSuccess) {
                log.info("✅ API业务成功: {}", responseBody);
                return ApiExecutionResult.success(
                        response.getStatusCodeValue(),
                        responseBody
                );
            } else {
                // HTTP 200但业务失败
                String errorMsg = extractErrorMessage(responseBody);
                log.warn("❌ API业务失败: {} | 完整响应: {}", errorMsg, responseBody);
                return ApiExecutionResult.businessError(errorMsg, responseBody);
            }
            
        } catch (org.springframework.web.client.HttpStatusCodeException e) {
            // HTTP错误（4xx, 5xx）
            log.error("API返回HTTP错误: {} - {}", e.getStatusCode(), e.getResponseBodyAsString());
            
            String errorBody = e.getResponseBodyAsString();
            String errorMessage = extractDetailedError(e.getStatusCode().value(), errorBody);
            
            return ApiExecutionResult.httpError(
                    e.getStatusCode().value(),
                    errorMessage,
                    errorBody
            );
        } catch (Exception e) {
            log.error("API执行失败: " + e.getMessage(), e);
            return ApiExecutionResult.error("网络错误或系统异常：" + e.getMessage());
        }
    }
    
    /**
     * 检查业务是否成功
     */
    private boolean checkBusinessSuccess(String responseBody) {
        try {
            @SuppressWarnings("unchecked")
            Map<String, Object> result = objectMapper.readValue(responseBody, Map.class);
            Object code = result.get("code");
            
            // code为200表示成功
            if (code != null) {
                int codeInt = code instanceof Integer ? (Integer) code : Integer.parseInt(code.toString());
                return codeInt == 200;
            }
            
            return false;
        } catch (Exception e) {
            log.warn("解析业务结果失败，默认为成功: " + e.getMessage());
            return true; // 无法解析时默认成功
        }
    }
    
    /**
     * 提取错误信息
     */
    private String extractErrorMessage(String responseBody) {
        try {
            @SuppressWarnings("unchecked")
            Map<String, Object> result = objectMapper.readValue(responseBody, Map.class);
            Object message = result.get("message");
            return message != null ? message.toString() : "操作失败";
        } catch (Exception e) {
            return "操作失败";
        }
    }
    
    /**
     * 从HTTP错误响应中提取详细错误信息
     */
    private String extractDetailedError(int statusCode, String errorBody) {
        try {
            @SuppressWarnings("unchecked")
            Map<String, Object> errorJson = objectMapper.readValue(errorBody, Map.class);
            
            StringBuilder errorMsg = new StringBuilder();
            errorMsg.append("HTTP ").append(statusCode).append(" 错误");
            
            // 提取错误类型
            Object error = errorJson.get("error");
            if (error != null) {
                errorMsg.append("：").append(error);
            }
            
            // 提取错误消息
            Object message = errorJson.get("message");
            if (message != null && !message.toString().isEmpty()) {
                errorMsg.append("\n详细信息：").append(message);
            }
            
            // 提取路径
            Object path = errorJson.get("path");
            if (path != null) {
                errorMsg.append("\n接口：").append(path);
            }
            
            return errorMsg.toString();
            
        } catch (Exception e) {
            // 无法解析JSON，返回原始错误
            return "HTTP " + statusCode + " 错误：" + errorBody;
        }
    }
    
    /**
     * 构建完整URL
     */
    private String buildUrl(ApiMetadata api, Map<String, Object> parameters) {
        String baseUrl = "http://localhost:" + serverPort + contextPath;
        String path = api.getPath();
        
        // 替换路径变量
        if (api.getParameters() != null) {
            for (ApiMetadata.ApiParameter param : api.getParameters()) {
                if ("path".equals(param.getLocation())) {
                    String paramName = param.getName();
                    Object paramValue = parameters.get(paramName);
                    if (paramValue != null) {
                        path = path.replace("{" + paramName + "}", String.valueOf(paramValue));
                    }
                }
            }
        }
        
        // 构建查询参数
        StringBuilder queryParams = new StringBuilder();
        if (api.getParameters() != null) {
            for (ApiMetadata.ApiParameter param : api.getParameters()) {
                if ("query".equals(param.getLocation())) {
                    Object paramValue = parameters.get(param.getName());
                    if (paramValue != null) {
                        if (queryParams.length() > 0) {
                            queryParams.append("&");
                        }
                        queryParams.append(param.getName()).append("=").append(paramValue);
                    }
                }
            }
        }
        
        String url = baseUrl + path;
        if (queryParams.length() > 0) {
            url += "?" + queryParams.toString();
        }
        
        return url;
    }
    
    /**
     * 构建请求头
     */
    private HttpHeaders buildHeaders(ApiMetadata api, String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        if (api.isRequireAuth() && token != null && !token.isEmpty()) {
            headers.set("Authorization", "Bearer " + token);
        }
        
        return headers;
    }
    
    /**
     * 构建请求体
     */
    private Object buildRequestBody(ApiMetadata api, Map<String, Object> parameters) {
        if (parameters == null || parameters.isEmpty()) {
            return null;
        }
        
        // 优先检查是否有"body"键（AI生成的格式）
        if (parameters.containsKey("body")) {
            Object bodyContent = parameters.get("body");
            log.info("从parameters.body中提取请求体: {}", bodyContent);
            return bodyContent;
        }
        
        // 兼容旧格式：检查API元数据中定义的body参数
        if (api.getParameters() != null) {
            for (ApiMetadata.ApiParameter param : api.getParameters()) {
                if ("body".equals(param.getLocation())) {
                    Object bodyContent = parameters.get(param.getName());
                    log.info("从API参数定义中提取请求体: {}", bodyContent);
                    return bodyContent;
                }
            }
        }
        
        // 如果是POST/PUT请求但没有明确的body，尝试使用整个parameters作为请求体
        if ("POST".equals(api.getMethod()) || "PUT".equals(api.getMethod())) {
            log.info("使用整个parameters作为请求体: {}", parameters);
            return parameters;
        }
        
        return null;
    }
    
    /**
     * API执行结果
     */
    public static class ApiExecutionResult {
        private boolean success;
        private int statusCode;
        private String response;
        private String error;
        private boolean businessError; // 是否是业务层错误
        
        public static ApiExecutionResult success(int statusCode, String response) {
            ApiExecutionResult result = new ApiExecutionResult();
            result.success = true;
            result.statusCode = statusCode;
            result.response = response;
            result.businessError = false;
            return result;
        }
        
        public static ApiExecutionResult businessError(String errorMsg, String response) {
            ApiExecutionResult result = new ApiExecutionResult();
            result.success = false;
            result.error = errorMsg;
            result.response = response;
            result.businessError = true;
            return result;
        }
        
        public static ApiExecutionResult httpError(int statusCode, String errorMsg, String response) {
            ApiExecutionResult result = new ApiExecutionResult();
            result.success = false;
            result.statusCode = statusCode;
            result.error = errorMsg;
            result.response = response;
            result.businessError = false;
            return result;
        }
        
        public static ApiExecutionResult error(String error) {
            ApiExecutionResult result = new ApiExecutionResult();
            result.success = false;
            result.error = error;
            result.businessError = false;
            return result;
        }
        
        public boolean isSuccess() {
            return success;
        }
        
        public int getStatusCode() {
            return statusCode;
        }
        
        public String getResponse() {
            return response;
        }
        
        public String getError() {
            return error;
        }
        
        public boolean isBusinessError() {
            return businessError;
        }
        
        @Override
        public String toString() {
            if (success) {
                return "API执行成功 (状态码: " + statusCode + ")\n结果: " + response;
            } else {
                return "API执行失败: " + error;
            }
        }
    }
}

